package host.skiree.nettydemo.protocol;

import host.skiree.nettydemo.config.Config;
import host.skiree.nettydemo.message.Message;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * @author gcl
 * @date 2022/9/16 15:27
 * 必须和LengthFieldBasedFrameDecoder一起使用，确保接收的ByteBuf是完整的
 */
@Slf4j
@ChannelHandler.Sharable
public class MessageCodecSharable extends MessageToMessageCodec<ByteBuf, Message> {
    @Override
    protected void encode(ChannelHandlerContext ctx, Message msg, List<Object> outList) throws Exception {
        ByteBuf out = ctx.alloc().buffer();
        // 4 约定魔数
        out.writeBytes(new byte[]{20, 22, 9, 16});
        // 1 版本号
        out.writeByte(1);
        // 1 序列化方式 (0-JDK 1-JSON)
        out.writeByte(Config.getSerializType().ordinal());
        // 1 指令类型
        out.writeByte(msg.getMessageType());
        // 4 请求序号
        out.writeInt(msg.getSequenceId());
        // 对象序列化为字节数组
        /**
         *         ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
         *         ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
         *         objectOutputStream.writeObject(msg);
         */
        byte[] bytes = Config.getSerializType().serializ(msg);
        // 4 长度
        out.writeInt(bytes.length);
        // 1 无意义 仅对齐填充使固定长度为2的整数倍
        out.writeByte(0xff);
        // 内容
        out.writeBytes(bytes);
        // 传播到下一个handler
        outList.add(out);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        int magicNum = in.readInt();
        byte version = in.readByte();
        int serializerType = in.readByte();
        int messageType = in.readByte();
        int sequenceId = in.readInt();
        int length = in.readInt();
        in.readByte();
        byte[] bytes = new byte[length];
        in.readBytes(bytes, 0, length);
        // 查询反序列化算法
        Serializ.Type type = Serializ.Type.values()[serializerType];
        Class<? extends Message> mClass = Message.getMessageClass(messageType);
        Message message = type.deserializ(mClass,bytes);
        out.add(message);
//        if ( serializerType == 0){
            // 字节数组反序列化为对象
            /**
             *             ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
             *             ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
             *             Message message = (Message) objectInputStream.readObject();
             */
//            log.debug("{}, {}, {}, {}, {}, {}", magicNum, version, serializerType, messageType, sequenceId, length);
//            log.debug("{}", message);
            // 加入到out集合，后续的handler还要使用
//            out.add(message);
//        }
    }
}
